<?php
$loader->requireOnce('includes/Billing.class.php');
$loader->requireOnce('includes/CorePayment/CorePaymentCalculator.class.php');
$loader->requireOnce('includes/CorePayment/BillStorage.class.php');
$loader->requireOnce('includes/CorePayment/OutPatientBillMaker/OutPatientBillMaker.class.php');
$loader->requireOnce('includes/Insurance/InsuranceInfo.class.php');
$loader->requireOnce('includes/EnumerationConstant.class.php');
$loader->requireOnce('includes/Utils.class.php');
$loader->requireOnce('includes/DiscountManager/DiscountManager.class.php');
class PaymentProcessor {
    private $controller;
    private $db;

    function __construct($controller = null){
        $this->db   =   $GLOBALS['frame']['adodb']['db'];
        if (!is_null($controller)) {
            $this->controller   =   $controller;
        }
    }

	public function createBillStorages($ticketId) {
		$list         =   array();
		$objTicket    =   Celini::newORDO('Ticket', $ticketId);
		$date         =   explode(" ", $objTicket->get('created'));

		// Step 1: Get insurance information of the ticket
        $infoArr      =   Celini::newORDO('TicketInsurance')->getInsuranceInfoByTicket($ticketId);
        if (count($infoArr) == 0) {
            $objStorage =   new  BillStorage($ticketId, $date[0], date('Y-m-d'), $objTicket->getEnumPatientType(),
                $objTicket->get('enum_examination_type'), $objTicket->get('sale_program_store_id'));
            $list[] =   $objStorage;
        }
        
        elseif (count($infoArr) == 1) {
            $objStorage =   new BillStorage($ticketId, $date[0], date('Y-m-d'), $objTicket->getEnumPatientType(),
                $objTicket->get('enum_examination_type'), $objTicket->get('sale_program_store_id'));
            $objInfo    =   new InsuranceInfo($infoArr[0]['insurance_id'],$infoArr[0]['insurance_code'],  $infoArr[0]['paid_for_36_month'],
                $infoArr[0]['correct_route'], $infoArr[0]['date_issued'], $infoArr[0]['date_expired'], $infoArr[0]['hospital_name']);
            $objStorage->setInsuranceInfo($objInfo);
            $list[] =   $objStorage;
        }
        elseif (count($infoArr) == 2) {
            // TODO ppdong 2009-12-08: Complete this case
        }

        // Step2: Create BillableItem lists for BillStorage objects
        foreach ($list as &$objStorage) {
            self::buildItems($objStorage);
        }

        // Step3: Force objects go through CorePaymentCalculator and DiscountManager
	   foreach ($list as &$objStorage) {
	   	   $corePayment    =   new CorePaymentCalculator($objStorage);
           $corePayment->calculate();

           $discount        =   new DisccountManager($objStorage);
           $discount->performDiscount();

           $billing         =   new Billing($objStorage);
           $billing->calculate();
        }

        return $list;
	}

	private function buildItems(&$objStorage) {
		// Case 1: OutPatient
		if ($objStorage->getPatientType() == EnumerationConstant::PATIENT_TYPE_OUTPATIENT_KEY) {
			// Check if the case of insurance
			$insInfo    =   $objStorage->getInsuranceInfo();
			$objBillMaker   =   new OutPatientBillMaker($objStorage);
			$objBillMaker->import(PaymentConstant::ITEM_SERVICE);
			if ($insInfo->getInsuranceGroup() !== false) {
				$objBillMaker->import(PaymentConstant::ITEM_MEDICINE);
			}
		}
		// Case 2: InPatient
		elseif($objStorage->getPatientType() == EnumerationConstant::PATIENT_TYPE_INPATIENT_KEY) {
			// TODO ppdong 2009-12-08 : Finish this case
		}
	}

	public function createBillStorageFromArray($data) {
        $objStorage =   new BillStorage($data['ticketId'], $data['startDate'], $data['endDate'],
            $data['patientType'], $data['examinationType'], $data['discountProgram']);
        foreach ($data['itemList'] as $item) {
        	$billableItem  =   new BillableItem($item['serviceId'], $item['serviceName'], $item['unit'],
        	   $item['quantity']);
            $billableItem->setOriginalUnitPrice($item['originalUnitPrice']);
            $billableItem->setInsurancePrice($item['insurancePrice']);
            $billableItem->setPatientPrice($item['patientPrice']);
            $billableItem->setDiscount($item['discount']);
            $billableItem->setType($item['itemType']);
            $billableItem->setChangePriceNote($item['changePriceNote']);
            $objStorage->addItem($item['itemType'], $billableItem);
        }
        return $objStorage;
	}

	static public function getInsuranceInfoObjects($ticketId) {
		$infoArr	=	Celini::newORDO('TicketInsurance')->getInsuranceInfoByTicket($ticketId);
		$res	=	array();
		foreach ($infoArr as $item) {
			$objInfo    =   new InsuranceInfo($item['insurance_id'],$item['insurance_code'],  $item['paid_for_36_month'],
				$item['correct_route'], $item['date_issued'], $item['date_expired'], $item['hospital_name']);
			array_push($res, $objInfo);
		}
		return $res;
	}
}
?>